﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace DmxInterface {

	/// <summary>
	/// Asynchronous implementation of IEngine.
	/// Continuosly sends updated to all registered DMX Devices at a certain frequency.
	/// </summary>
	class AsynchronousEngine : BaseEngine {

		Timer _timer;
		bool _working = false;

		OperativeFrequency _frequency = OperativeFrequency.Recommended;
		int _period;


		public AsynchronousEngine() {
			_timer = new Timer(new TimerCallback(TimerTick), null, Timeout.Infinite, Timeout.Infinite);
		}

		#region Interface

		public override void Start() {
			_working = true;
			UpdateTimer();
		}

		public override void Stop() {
			//Disable timer
			_timer.Change(Timeout.Infinite, Timeout.Infinite);

			_working = false;
		}

		public override OperativeFrequency Frequency {
			get {
				return _frequency;
			}
			set {
				_frequency = value;

				UpdateTimer();
			}
		}

		public override void Dispose() {
			_working = false;
			_timer.Dispose();
		}

		#endregion

		private void UpdateTimer() {
			//Switch
			switch (_frequency) {
				case OperativeFrequency.VeryHigh:
					_period = 1000 / 45; break;

				case OperativeFrequency.High:
					_period = 1000 / 35; break;

				case OperativeFrequency.Recommended:
					_period = 1000 / 25; break;

				case OperativeFrequency.Low:
					_period = 1000 / 10; break;

				case OperativeFrequency.VeryLow:
					_period = 1000 / 5; break;
			}

			_timer.Change(0, _period);
		}

		private void TimerTick(object o) {
			if (!_working)
				return;

			OnDataSending();

			foreach (C5.KeyValuePair<Device, Universe> pair in DeviceTable) {
				pair.Key.SendData(pair.Value.UniverseState);
			}

			OnDataSent();
		}

	}
}
